/*
    UUID字符串生成
    * UUID的标准型式包含32个16进制数字字符，以连字号分为五段，形式为8-4-4-4-12的32个16进制字符
    * 这里采用8个1字节随机数 + 一个8字节序号来生成UUID
*/


#pragma once

#include <random>
#include <iomanip>
#include <sstream>
#include <atomic>

namespace JsonMuduoRPC
{
    class UUID
    {
    public:
        static const std::string getUuidStr()
        {
            // UUID: 8-4-4-4-12的32个16进制数

            std::stringstream ss; // 用于存放uuid的字符流

            // 1. 创建一个机器随机数对象
            std::random_device rd;
            // 2. 将机器随机数作为种子，生成伪随机对象
            std::mt19937 genenrator(rd());
            // 3. 限制随机数范围 [0, 255]
            std::uniform_int_distribution<int> distibution(0, 255);

            // 随机生成8个16进制随机数 num1num2num3num4-num5num6-num7num8
            for (int i = 0; i < 8; i++)
            {
                if (i == 4 || i == 6)
                    ss << '-';
                ss << std::setw(2) << std::setfill('0') << std::hex << distibution(genenrator);
            }

            ss << '-';

            static std::atomic<size_t> seq(1); // 序号，每次加一
            size_t cur = seq.fetch_add(1);      //原子操作，保证线程安全

            // 还剩8个字节，每次取前1个字节（8位）
            for (int i = 7; i >= 0; --i)
            {
                if (i == 5)
                    ss << '-';
                ss << std::setw(2) << std::setfill('0') << std::hex << ((cur >> (i * 8)) & 0xff);
            }

            return ss.str();
        }
    };
} // namespace JsonMuduoRPC
